/*********************************************************
*Copyright (c) 2009 Rob Groves. All Rights in Pw 
*@des: 异步并发TCP client
*@name: client.h
*@author: zhongsx
*@time: 2015-02-27
*********************************************************/

#ifndef __CLIENT_H__
#define __CLIENT_H__

#include "msg.h"
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>  
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp> 
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/noncopyable.hpp>

//本地回调函数

//解析数据回调
class client;
typedef boost::function<void(boost::shared_ptr<client>& , boost::shared_ptr<message>& ) > CallBack_T;

typedef enum{
	FAIL	= -2,
	UNKONWN = -1,
	CONNCT	= 1,
	CLOSE	= 0,
	SESSION = 1001,
	CLIENT = 1002,
}CLIENT_TYPE;

class client :public boost::noncopyable, public boost::enable_shared_from_this<client>
	
{  
public:
	//接入连接
	client(boost::asio::io_service& ios, CallBack_T _func);
	
	//开启异步连接 
  	client(boost::asio::io_service& io_service, CallBack_T func, std::string ip, short port);

	virtual ~client();
	//
	boost::asio::ip::tcp::socket& socket();

	void start_read();
  	//将消息主动投递给io_service  
  	void write(boost::shared_ptr<message> msg);
  	//这个close函数是客户端要主动终止时调用
  	void close();
	inline int getsta() {return sta; }
	inline std::string geterrstr() { return errstr; }
private:  
	//连接回调
  	void handle_connect(const boost::system::error_code& error); 
  	//处理数据报头 
  	void handle_read_header(const boost::system::error_code& error, int bytes_);  
  	//处理数据包数据
  	void handle_read_msg(const boost::system::error_code& error, int bytes_);
  	//把要写的数据push至写队列 
  	void do_write(boost::shared_ptr<message> msg);
  	//第一个消息单独处理，剩下的才更好操作 
  	void handle_write(const boost::system::error_code& error);
  
  	void do_close(); 
	//超时
	void time_out(const boost::system::error_code& error);
public:
	int type; 
	std::string clientIp;
	short clientPort;
protected:
	//超时timer
	boost::asio::deadline_timer timer_;
private: 
	int sta;
	//错误信息
	std::string errstr;

  	boost::asio::io_service& io_service_;  
  	boost::asio::ip::tcp::socket socket_;  

  	//分别处理数据头和数据
  	CallBack_T func_;
  	//数据头长
  	//读数据缓冲
	boost::shared_ptr<message>	read_buf_;
  	std::list<boost::shared_ptr<message>> write_bufs_;   
};  


#endif //__CLIENT_H__